package com.xz.questions.bloomfilter;

import cn.hutool.bloomfilter.BitMapBloomFilter;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.yaml.snakeyaml.Yaml;

import java.util.List;
import java.util.Map;

/**
 * @author: 阿庆
 * @date: 2024/10/20 下午3:31
 * 布隆过滤器实现 黑名单
 */

@Slf4j
public class BlackIpUtils {

    private static BitMapBloomFilter bloomFilter;

    // 判断 ip 是否在黑名单中
    public static boolean isInBlackList(String ip) {
        return bloomFilter.contains(ip);
    }

    // 重建 黑名单 将其放入布隆过滤器中 （因为bloomFilter 无法删除，因此只能重建）
    public static void rebuildBlackList(String configInfo) {
        // 判断配置是否为空
        if (StringUtils.isBlank(configInfo)) {
            configInfo = "{}";
        }

        // 解析 yaml 文件
        Yaml yaml = new Yaml();

        // 参数：要解析的配置，解析成的类型
        Map<String,List<String>> map = yaml.loadAs(configInfo, Map.class);

        // 获取黑名单
        List<String> blackList = map.get("blackIpList");

        // 加锁，防止并发
        synchronized (BlackIpUtils.class) {
            if (CollUtil.isNotEmpty(blackList)) {
                // 重建布隆过滤器
                bloomFilter = new BitMapBloomFilter(1000);
                // 将黑名单放入布隆过滤器中
                for (String ip : blackList) {
                    bloomFilter.add(ip);
                }
            } else {
                bloomFilter = new BitMapBloomFilter(100);
            }
        }
    }
}
